A debugger is a software program that allows a user to debug other software programs. A user may initiate a debug session by starting up the debugger with the program being debugged, where the program being debugged may be referred to as the debuggee. The user may then set one or more breakpoints in the debuggee. A breakpoint is a mechanism to pause the debuggee when at least one condition associated with the breakpoint becomes true.
After setting the one or more breakpoints, the user may continue with the execution of the debuggee. When the debuggee is paused at a breakpoint, the user may check the debuggee's internal state, such as register values, memory values, and the call stack, to determine the cause of one or more bugs in the debuggee, where a bug is a defect in the debuggee. The user may set additional breakpoints, continue the execution of the debuggee, and check the debuggee's internal state in an attempt to determine the cause of the one or more bugs.
A watchpoint is a breakpoint that is triggered when the content of a specified memory address changes. A watchpoint may be implemented by changing the access protection of the page in which the specified memory address is located. For example, if the user sets a watchpoint to monitor writes to a variable, the page where the variable resides would be set to read-only protection. When the page is written into, the operating system may deliver a fault signal that indicates a page access violation. As a result, the debuggee may be paused. The page access violation may be referred to as a segmentation violation (SEGV). The debugger may receive the fault signal and determine the memory address where the write failed. The debugger may then change the protection of the page back to write-allowed and single step the instruction that resulted in the fault signal. When the single stepping completes (whether the single stepping succeeds or not), the debugger may reset the protection on the page to read-only to identify additional subsequent writes to the memory address. If the single stepping succeeds, the debugger either notifies the user of a watchpoint hit if the address falls within the memory address corresponding to a watchpoint, or resumes the debuggee if the address falls outside the memory address corresponding to any watchpoints. If the single stepping fails, then the debugger may report that a program error has occurred. A debugger that uses memory protection to handle watchpoints may be referred to as an “SEGV debugger”.